/**
 *
 * @param table {Table}
 * @param auth {boolean} 接口是否需要鉴权
 * @param uninstall {boolean} 是否在生成代码时注释该方法，用于备用
 * @returns {string}
 */
const IJavaNameRepository = (table, auth = false, uninstall = false) => {
  const {
    idType,
    names: {
      TabName,
      JavaName
    }
  } = table
  // const authUser = auth ? ', final Long userId' : ''
  // const authUserId = auth ? '.createUserId(userId)' : ''
  return `// <-
   /**
     * 如果该表有缓存时请使用缓存，将这段代码注释，然后组合缓存接口。
     * 组合模式：定义表数据无缓存时，优化连表查询方法.
     * 实体类只需要组合该接口就可以获得按 id 查询方法.
     * 这种实现方式可以分解连表查询，减轻数据库压力，对分页查询有优化，让单表查询方法复用范围更广
     * 使用参考：
     * <pre>
     * public class TabEntity implements I${JavaName}Repository{
     *     private ${idType} foreignKey;
     *     private Set<${idType}> foreignKeys;
     *
     *     public ${TabName} getForeign(){
     *         // 连表查询单条记录
     *         return get${TabName}ById(foreignKey).orElse(null);
     *     }
     *     public List<${TabName}> getForeigns(){
     *         // 连表查询多条记录
     *         return list${TabName}ByIds(foreignKeys);
     *     }
     * }
     * </pre>
     */
    interface I${JavaName}Repository {
        /**
         * 按 ID 获取数据行，用于表数据无缓存时，优化连表查询
         *
         * @param id {@link ${TabName}#getId()}
         * @return {@link Optional<${TabName}>}
         */
        @JSONField(serialize = false, deserialize = false)
        default Optional<${TabName}> get${TabName}ById(final ${idType} id) {
            return getBean(${JavaName}Repository.class).findById(id).map(${TabName}::cloneObject);
        }
        /**
         * 按 ID 获取数据行，用于表数据无缓存时，优化连表查询
         *
         * @param ids {@link ${TabName}#getId()}
         * @return {@link List<${TabName}>}
         */
        @JSONField(serialize = false, deserialize = false)
        default List<${TabName}> list${TabName}ByIds(final Set<${idType}> ids) {
            return getBean(${JavaName}Repository.class).findAllById(ids).stream()
                    .sorted(Comparator.comparing(${TabName}::getId).reversed())
                    .map(${TabName}::cloneObject)
                    .collect(Collectors.toList());
        }
    }
`.split('\n')
    .map(row => (uninstall ? '//' : '') + row)
    .join('\n')
}
export const iJavaNameRepositoryOpenInstall = table => IJavaNameRepository(table)
export const iJavaNameRepositoryOpenUninstall = table => IJavaNameRepository(table, false, true)

export const iJavaNameRepositoryAuthInstall = table => IJavaNameRepository(table, true, false)
export const iJavaNameRepositoryAuthUninstall = table => IJavaNameRepository(table, true, true)
